#ifndef AFCORE_COMMON_LOG_ASYNC_ASYNC_LOGGER_
#define AFCORE_COMMON_LOG_ASYNC_ASYNC_LOGGER_

#include "logcommon.h"
#include "logger.h"

namespace afcore {

/// @brief  日志
namespace log {

/// @brief  异步记录器
class AFCORE_COMMON_API CAsyncLogger final
  : public std::enable_shared_from_this<CAsyncLogger>
  , public CLogger {
private:
  friend class CAsyncThreadPool;
public:
  /// @brief  构造函数
  /// @tparam It              记录器迭代器类型
  /// @param  logger_name     记录器名称
  /// @param  begin           记录器容器范围开始
  /// @param  end             记录器容器范围结束
  /// @param  tp              线程池
  /// @param  overflow_policy 阻塞策略
  template<typename It>
  CAsyncLogger(std::string logger_name, It begin, It end, RAsyncThreadPoolWptr tp,
    EAsyncOverflowPolicy overflow_policy = EAsyncOverflowPolicy::kAsyncOverflowPolicy_Block)
    : CLogger(std::move(logger_name), begin, end)
    , thread_pool_(std::move(tp))
    , overflow_policy_(overflow_policy) {
  }

  /// @brief  构造函数
  /// @param  logger_name     记录器名称
  /// @param  appenders       记录器初始化列表
  /// @param  tp              线程池
  /// @param  overflow_policy 阻塞策略
  CAsyncLogger(std::string logger_name, RAppenderInitList appenders, RAsyncThreadPoolWptr tp,
    EAsyncOverflowPolicy overflow_policy = EAsyncOverflowPolicy::kAsyncOverflowPolicy_Block);

  /// @brief  构造函数
  /// @param  logger_name     记录器名称
  /// @param  single_appender 单个记录器
  /// @param  tp              线程池
  /// @param  overflow_policy 阻塞策略
  CAsyncLogger(std::string logger_name, RAppenderSptr single_appender, RAsyncThreadPoolWptr tp,
    EAsyncOverflowPolicy overflow_policy = EAsyncOverflowPolicy::kAsyncOverflowPolicy_Block);

  std::shared_ptr<CLogger> CLone(std::string logger_name) override;

protected:
  /// @brief  所有追加器记录日志
  /// @param  msg                 日志信息
  virtual void AppenderDoLog(const SLogMessage& msg) override;
  /// @brief  刷新
  virtual void DoFlush();
  /// @brief  后端记录器日志
  /// @param  incoming_log_msg    异步日志消息
  void BackendAppenderDoLog(SLogMessage& incoming_log_msg);
  /// @brief  后端记录器刷新
  void BackendDoFlush();

private:
  RAsyncThreadPoolWptr thread_pool_;      ///< 线程池
  EAsyncOverflowPolicy overflow_policy_;  ///< 阻塞策略
};

} // !namespace log

} // !namespace afcore

#endif //! AFCORE_COMMON_LOG_ASYNC_ASYNC_LOGGER_